/*
 * @Author: Turump 
 * @Date: 2021-03-29 15:49:44 
 * @Last Modified by: Turump
 * @Last Modified time: 2021-05-13 17:42:30
 * 任务基类，进场，拖动到目标区域等任务带有目的性的动作，统称任务
 * !!! 继承此类的方法，请务必调用super.***, 不然肯定是会出BUG的
 */

import CocosHelper from "../helper/CocosHelper";
import EventCenter from "../helper/EventCenter";
import { TaskEnableType } from "./TaskEnableType";

const { ccclass, property } = cc._decorator;

@ccclass
export class TaskBase extends cc.Component {

    @property({ type: cc.Enum(TaskEnableType), displayName: "任务启动类型" })
    enableType: TaskEnableType = TaskEnableType.None;

    @property({ displayName: "延迟时间(秒)" })
    delayTime = 0

    @property({
        displayName: "触发启动事件",
        tooltip: "多个事件都发生触发,用;分号隔开",
        visible() { return this.enableType == TaskEnableType.SingleEvent }
    })
    eventString = ""

    @property({ displayName: "完成Emit事件", tooltip: "任务完成Emit事件" })
    doneEvent = ""

    @property({ displayName: "任务支持暂停" })
    isPauseable = false;
    @property({ displayName: "触发暂停的事件", visible() { return this.isPauseable } })
    pauseEventName = ""
    @property({ displayName: "触发恢复的事件", visible() { return this.isPauseable } })
    resumeEventName = ""
    @property({ displayName: "触发停用的事件", visible() { return this.isPauseable } })
    stopEventName = ""

    @property({ displayName: "重复任务" })
    repeatableTask = false;

    _eventNames: string[] = []
    _eventHappenedCount = 0;

    onLoad() {
    }

    start() {
        if (this.enableType == TaskEnableType.OnStart) {
            this.scheduleOnce(this.enableTask, this.delayTime);
        }
        else if (this.enableType == TaskEnableType.SingleEvent) {
            let events = this.eventString.split(";")
            events.forEach((event: string) => {
                this._eventNames.push(event);
                cc.log(`${this.name} 监听一次性事件:${event}`)
                if (event.length > 0) {
                    //复杂任务此处不支持重复
                    if(this.repeatableTask && (events.length == 1))
                        EventCenter.on(event, this.eventHappened, this);
                    else
                        EventCenter.once(event, this.eventHappened, this);
                }
            })
        }
        if (this.isPauseable) {
            (this.pauseEventName.length > 0) && EventCenter.on(this.pauseEventName, this.pauseTask, this);
            (this.resumeEventName.length > 0) && EventCenter.on(this.resumeEventName, this.resmueTask, this);
            (this.stopEventName.length > 0) && EventCenter.on(this.stopEventName, this.stopTask, this);
        }
    }

    onDestroy() {
        console.log(`${this.name} destory`);
        let events = this.eventString.split(";")
        events.forEach((event: string) => {
            this._eventNames.push(event);
            if (event.length > 0) {
                EventCenter.off(event, this.eventHappened, this);
            }
        })
        if (this.isPauseable) {
            (this.pauseEventName.length > 0) && EventCenter.off(this.pauseEventName, this.pauseTask, this);
            (this.resumeEventName.length > 0) && EventCenter.off(this.resumeEventName, this.resmueTask, this);
            (this.stopEventName.length > 0) && EventCenter.off(this.stopEventName, this.stopTask, this);
        }
    }

    eventHappened() {
        this._eventHappenedCount++;
        cc.log(`${this.name} eventHappened:${this._eventHappenedCount} need:${this._eventNames.length}`)
        if (this._eventHappenedCount == this._eventNames.length ||
            this.repeatableTask && this._eventNames.length == 1 ) {
            this.scheduleOnce(this.enableTask, this.delayTime);
        }
    }

    //启动任务
    enableTask() {
        cc.log(`${this.name} enableTask`);
    }

    //暂停任务
    pauseTask() {
        cc.log(`${this.name} pauseTask`);
    }

    //恢复任务
    resmueTask() {
        cc.log(`${this.name} resmueTask`);
    }

    stopTask() {
        cc.log(`${this.name} stopTask`);
        this.pauseTask();
        this.enabled = false;
    }

    emitDoneEvent() {
        if (this.doneEvent.length > 0) {
            cc.log(`${this.name} emitDoneEvent:${this.doneEvent} node:${this.node.name}`)
            EventCenter.emit(this.doneEvent, this.node)
        }
    }
}
